package com.example.demo.thread.util;

import org.apache.commons.net.util.Base64;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

/**
 * @author: htc
 * @date: Created in 14:50 2019/1/11.
 */
public class DESEncryption {
    public static class CryptoException extends Exception {
        private static final long serialVersionUID = 1L;

        public CryptoException(Exception cause) {
            super(cause);
        }
    }

    /**
     * 加密
     *
     * @param content 待加密内容
     * @param key     加密的秘钥
     * @return
     */
    public static byte[] encrypt(String content, String key) {
        byte[] result = null;
        try {
            DESKeySpec desKey = new DESKeySpec(key.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            result = cipher.doFinal(content.getBytes());
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String encryptAsString(String content, String key) throws CryptoException {
        byte[] encryptedBytes = encrypt(content, key);
        byte[] bytesEncoded = new Base64().encode(encryptedBytes);
        try {
            return new String(bytesEncoded, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new CryptoException(e);
        }
    }

    public static String decrypt(byte[] content, String key) throws CryptoException {
        try {
            DESKeySpec desKey = new DESKeySpec(key.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] result = cipher.doFinal(content);
            return new String(result, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            throw new CryptoException(e);
        }
    }

    public static String decryptString(String content, String key) throws CryptoException {
        byte[] bytesDecoded;
        try {
            bytesDecoded = new Base64().decode(content.getBytes("UTF-8"));
            return decrypt(bytesDecoded, key);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new CryptoException(e);
        }
    }

    public static void main(String[] args) throws CryptoException {
        String content = "secret content中文";
        // 密码长度必须是8的倍数
        String password = "12345678";
        System.out.println("密钥：" + password);
        System.out.println("加密前：" + content);
        String result = encryptAsString(content, password);
        System.out.println("加密后：" + result);
        String decryResult = decryptString(result, password);
        System.out.println("解密后：" + decryResult);
    }
}
